from functools import lru_cache
from typing import Any

import numpy as np
import pandas as pd

from model.FaultDetectionConfig import FaultDetectionConfig


class SignalProcessor:
    """信号处理工具类"""

    @staticmethod
    @lru_cache(maxsize=128)
    def compute_rms_by_dft(signal: np.ndarray, fs: int, freq: float = 50.0) -> float:
        """
        使用DFT方法计算基波分量的有效值

        Args:
            signal: 输入信号
            fs: 采样率
            freq: 基波频率

        Returns:
            有效值
        """
        N = len(signal)
        min_samples = int(fs / freq)

        if N < min_samples:
            return np.nan

        X = np.fft.fft(signal, n=N)
        X1 = X[1]  # 基波分量
        A = 2 * np.abs(X1) / N
        return round(A / np.sqrt(2), 6)

    @staticmethod
    def compute_rms_standard(signal: np.ndarray) -> float | None:
        """计算标准RMS值"""
        if len(signal) == 0:
            return None
        return round(np.sqrt(np.mean(signal ** 2)), 6)

    @staticmethod
    def extract_cycle_data(df: pd.DataFrame, center_time: pd.Timestamp,
                           cycle_offset: int, config: FaultDetectionConfig) -> pd.DataFrame:
        """
        提取指定周期的数据

        Args:
            df: 数据DataFrame
            center_time: 中心时间点
            cycle_offset: 周期偏移（负数表示之前，正数表示之后）
            config: 配置对象

        Returns:
            周期数据
        """
        samples_per_cycle = int(config.fs / config.freq)
        center_idx = df.index.get_indexer([center_time], method='nearest')[0]

        if cycle_offset < 0:
            start_idx = center_idx + cycle_offset * samples_per_cycle
            end_idx = start_idx + samples_per_cycle
        else:
            start_idx = center_idx + (cycle_offset - 1) * samples_per_cycle
            end_idx = start_idx + samples_per_cycle

        start_idx = max(0, start_idx)
        end_idx = min(len(df), end_idx)

        return df.iloc[start_idx:end_idx]